package com.sws.weixin.service.impl;

import com.alibaba.fastjson.JSONObject;

import com.sws.customer.ball.WxCustomerBinder;
import com.sws.weixin.common.message.MessageUtil;
import com.sws.weixin.common.util.HttpUtil;
import com.sws.weixin.entity.SubscribedUser;
import com.sws.weixin.entity.TUser;
import com.sws.weixin.entity.TestAppidSerectVO;
import com.sws.weixin.mapper.TUser2Mapper;
import com.sws.weixin.message.Article;
import com.sws.weixin.message.NewsMessage;
import com.sws.weixin.message.TextMessage;
import com.sws.weixin.service.StaffWxBinder;
import com.sws.weixin.service.WxService;
import com.sws.weixin.util.WordUtil;
import com.thoughtworks.xstream.XStream;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.json.JSONArray;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import jakarta.servlet.ServletInputStream;
import jakarta.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.*;

/**
 * @author Thor
 * @公众号 Java架构栈
 */
@Service
public class WxServiceImpl implements WxService {

    @Value("${redirect.domain}")
    private String redirectDomain;
    @Value("${wx.appid}")
    private String appId;
    @Value("${wx.secret}")
    private String secret;
    @Autowired
    private TUser2Mapper userMapper;
    @Autowired
    private WxCustomerBinder wxCustomerBinder;
    
    @Autowired
    private StaffWxBinder staffWxBinder; // 微信模块的实现

    @Override
    public TestAppidSerectVO testapplicatio(){
        TestAppidSerectVO testAppidSerectVO = new TestAppidSerectVO();
        testAppidSerectVO.setAppId(appId);
        testAppidSerectVO.setSecret(secret);
        testAppidSerectVO.setRedirectDomain(redirectDomain);
        return testAppidSerectVO;
    }
    
    @Override
    public String getStaffAuthUserInfo(String code) {
        // 根据code获取Access_token的地址
        String url = String.format("https://api.weixin.qq.com/sns/oauth2/access_token?appid=%s&secret=%s&code=%s&grant_type=authorization_code",
                appId,
                secret,
                code);
        // 发送get请求获得access_token
        String result = HttpUtil.doGet(url);
        String accessToken = JSONObject.parseObject(result).getString("access_token");
        String openId = JSONObject.parseObject(result).getString("openid");
        // 拿到access-token后拉取用户的基本信息
        String userInfoUrl = String.format("https://api.weixin.qq.com/sns/userinfo?access_token=%s&openid=%s&lang=zh_CN",
                accessToken,
                openId);
        // 拉取用户信息
        String userInfo = HttpUtil.doGet(userInfoUrl);
        // 解析获得微信号、昵称、头像
        SubscribedUser user = JSONObject.parseObject(userInfo, SubscribedUser.class);
        // 存入微信号昵称对应表（复用现有的用户表）
        TUser tUser = new TUser();
        BeanUtils.copyProperties(user, tUser);
        try {
            userMapper.insertSelective(tUser);
        } catch (Exception e) {
            System.err.println("保存用户信息失败: " + e.getMessage());
        }
        
        // 重定向到工作人员认证页面，传递openid参数
        return "<script>window.location.href='/wx/staffAuth?openid=" + openId + "';</script>";
    }
    
    @Override
    public Map<String, Object> bindWxUserToStaff(String name, String phone, String openid) {
        // 调用StaffWxBinder的方法处理绑定逻辑
        return staffWxBinder.bindWxUserToStaff(name, phone, openid);
    }
    
    @Override
    public String handleMessage(ServletInputStream inputStream, HttpServletRequest request) throws IOException, DocumentException {
        ServletInputStream inputStream2 = request.getInputStream();
        Map<String,String> map = new HashMap<>();
        SAXReader reader = new SAXReader();
        try {
            //读取request输入流，获得Document对象
            Document document = reader.read(inputStream2);
            //获得root节点
            Element root = document.getRootElement();
            //获取所有的子节点
            List<Element> elements = root.elements();
            for (Element element : elements) {
                map.put(element.getName(),element.getStringValue());
            }
        } catch (DocumentException e) {
            e.printStackTrace();
        }
        System.out.println(map);
        String msgType = map.get("MsgType");
        String message = "";
        switch (msgType){
            case "text":
                //回复同义词
                if("图文".equals(map.get("Content"))){
                    message = getReplyNewsMessage(map);
                } else if ("认证".equals(map.get("Content"))) {
                    //获得用户授权，拉取用户信息，存入微信号昵称对应表
                    message = createSignUpRedirectUri(map);
                } else{
                    message = getReplyMessageByWord(map);
                }
                break;
            case "event":
                message = handleEvent(map);
                break;
/*            case "image":
                message = handleImage(map);
                break;*/
            default:
                break;

        }

//        String message = getReplyMessage(map);
        return message;
    }


/*
    @PostMapping("/")
    public String receiveMessage(HttpServletRequest request) throws IOException {
        ServletInputStream inputStream = request.getInputStream();
        Map<String,String> map = new HashMap<>();
        SAXReader reader = new SAXReader();
        try {
            //读取request输入流，获得Document对象
            Document document = reader.read(inputStream);
            //获得root节点
            Element root = document.getRootElement();
            //获取所有的子节点
            List<Element> elements = root.elements();
            for (Element element : elements) {
                map.put(element.getName(),element.getStringValue());
            }
        } catch (DocumentException e) {
            e.printStackTrace();
        }
        System.out.println(map);
        String msgType = map.get("MsgType");
        String message = "";
        switch (msgType){
            case "text":
                //回复同义词
                if("图文".equals(map.get("Content"))){
                    message = getReplyNewsMessage(map);
                }else{
                    message = getReplyMessageByWord(map);

                }
                break;
            case "event":
                message = handleEvent(map);
                break;
            case "image":
                message = handleImage(map);
                break;
            default:
                break;

        }

//        String message = getReplyMessage(map);
        return message;
    }
* */

    //裂变进来的用户
    @Override
    public String getUserInfo(String code) throws IOException, DocumentException {
        //根据code获取Access_token的地址
        String url = String.format("https://api.weixin.qq.com/sns/oauth2/access_token?appid=%s&secret=%s&code=%s&grant_type=authorization_code",
                appId,
                secret,
                code);
        //发送get请求获得access_token
        String result = HttpUtil.doGet(url);
        String accessToken = JSONObject.parseObject(result).getString("access_token");
        String openId = JSONObject.parseObject(result).getString("access_token");
        //拿到access-token后拉取用户的基本信息 access_token openid
        String userInfoUrl = String.format("https://api.weixin.qq.com/sns/userinfo?access_token=%s&openid=%s&lang=zh_CN",
                accessToken,
                openId);
        //拉取用户信息
        String userInfo = HttpUtil.doGet(userInfoUrl);
        //解析获得微信号、昵称、头像
        SubscribedUser user = JSONObject.parseObject(userInfo, SubscribedUser.class);
        //存入微信号昵称对应表
        TUser tUser = new TUser();
        BeanUtils.copyProperties(user, tUser);
        try {
            userMapper.insertSelective(tUser);
        } catch (Exception e) {
            //log.log(e.getMessage());
        }
        return "<h2>关注成功，请返回。参加活动请在公众号输入：</h2><h1>报名</h1>";
    }

    /**
     * 获取请求消息中的xml
     *
     * @param inputStream
     * @return
     * @throws IOException
     * @throws DocumentException
     */
    private Map<String, String> getRequestMap(ServletInputStream inputStream) throws IOException, DocumentException {
        Map<String, String> map = new HashMap<>();
        SAXReader reader = new SAXReader();
        //读取request输入流，获得Document对象
        Document document = reader.read(inputStream);
        //获得root节点
        Element root = document.getRootElement();
        //获取所有的子节点
        List<Element> elements = root.elements();
        for (Element element : elements) {
            map.put(element.getName(), element.getStringValue());
        }
        return map;
    }

    /*
   引导报名活动用户访问地址进行授权，之后改用模版消息来封装
*/
    private String createSignUpRedirectUri(Map<String, String> map) {
        //获得关注者的信息（微信号、昵称、头像等）并存入微信号昵称对应表
        //先引导用户访问地址进行授权，之后改用模版消息来封装
        String redirectUrl;
        try {
            // 清理域名中可能存在的路径部分
            String cleanDomain = redirectDomain;
            if (cleanDomain.contains("/")) {
                cleanDomain = cleanDomain.split("/")[0];
            }
            
            // 正确编码重定向URL
            redirectUrl = URLEncoder.encode("http://" + cleanDomain + "/wx/getSignUpUserInfo", "UTF-8");
        } catch (UnsupportedEncodingException e) {
            System.err.println("URL编码失败: " + e.getMessage());
            redirectUrl = "http://" + redirectDomain + "/wx/getSignUpUserInfo";
        }
        
        String url = String.format("https://open.weixin.qq.com/connect/oauth2/authorize?appid=%s&redirect_uri=%s&response_type=code&scope=%s#wechat_redirect",
                appId,
                redirectUrl,
                "snsapi_userinfo");
                
        System.out.println("生成的认证授权URL: " + url);
        
        String xml = MessageUtil.generateTextMessageForXML(map, "点击链接：<a href=\"" + url + "\">参与活动</a>");
        return xml;
    }


    /**
     * 拉取主动获取海报的用户信息
     *
     * @param code
     * @return
     */
    @Override
    public String getSignUpUserInfo(String code) {
        //根据code获取Access_token的地址
        String url = String.format("https://api.weixin.qq.com/sns/oauth2/access_token?appid=%s&secret=%s&code=%s&grant_type=authorization_code",
                appId,
                secret,
                code);
        //发送get请求获得access_token
        String result = HttpUtil.doGet(url);
        String accessToken = JSONObject.parseObject(result).getString("access_token");
        String openId = JSONObject.parseObject(result).getString("openid");
        //拿到access-token后拉取用户的基本信息 access_token openid
        String userInfoUrl = String.format("https://api.weixin.qq.com/sns/userinfo?access_token=%s&openid=%s&lang=zh_CN",
                accessToken,
                openId);
        //拉取用户信息
        String userInfo = HttpUtil.doGet(userInfoUrl);
        //解析获得微信号、昵称、头像
        SubscribedUser user = JSONObject.parseObject(userInfo, SubscribedUser.class);
        // 存入微信号昵称对应表
        TUser tUser = new TUser();
        BeanUtils.copyProperties(user, tUser);
        try {
            userMapper.insertSelective(tUser);
        } catch (Exception e) {
            System.err.println("保存用户信息失败: " + e.getMessage());
        }
        
        // 使用重定向到注册页面，并传递openid参数
        return "<script>window.location.href='/wx/register?openid=" + openId + "';</script>";
    }

    /**
     * 报名成功的html
     *
     * @return
     */
    private String getSignUpHtml() {
        //return "<h2>报名成功，返回后请在公众号输入关键字：</h2><h1>海报</h1><h2>分享活动海报，邀请好友扫码助力，输入\"排行榜\"查看助力排行榜</h2>";
        String html = "<!doctype html>\n" +
                "<html lang=\"zh-CN\">\n" +
                "  <head>\n" +
                "    <meta charset=\"utf-8\">\n" +
                "    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n" +
                "    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n" +
                "    <title>活动详情</title>\n" +
                "    <link rel=\"stylesheet\" href=\"https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css\" integrity=\"sha384-HSMxcRTRxnN+Bdg0JdbxYKrThecOKuH5zCYotlSAcp1+c8xmyTe9GYg1l9a69psu\" crossorigin=\"anonymous\">\n" +
                "  </head>\n" +
                "  <body>\n" +
                "\t  <div class=\"container\">\n" +
                "\t\t  <div class=\"row\">\n" +
                "\t\t\t  <blockquote>\n" +
                "\t\t\t    <p>恭喜你，报名成功！</p>\n" +
                "\t\t\t  </blockquote>\n" +
                "\t\t  </div>\n" +
                "\t  </div>\n" +
                "    <script src=\"https://cdn.jsdelivr.cn/npm/jquery@1.12.4/dist/jquery.min.js\" integrity=\"sha384-nvAa0+6Qg9clwYCGGPpDQLVpLNn0fRaROjHqs13t4Ggj3Ez50XnGQqc/r8MhnRDZ\" crossorigin=\"anonymous\"></script>\n" +
                "<script src=\"https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js\" integrity=\"sha384-aJ21OjlMXNL5UyIl/XNwTMqvzeRMZH2w8c5cRVpzpU8Y5bApTppSuUkhZXN0VxHd\" crossorigin=\"anonymous\"></script>\n" +
                "  </body>\n" +
                "</html>";
        return html;
    }


    /**
     * 图片文字识别处理
     *
     * @param map
     * @return
     */
  /*  private String handleImage(Map<String, String> map) {
        // 初始化一个AipOcr
        AipOcr client = new AipOcr(APP_ID, API_KEY, SECRET_KEY);
        // 网络图片文字识别, 图片参数为远程url图片
        String url = map.get("PicUrl");
        org.json.JSONObject res = client.webImageUrl(url, new HashMap<String, String>());
        //解析内容，生成返回的数据
        JSONArray wordsResult = res.getJSONArray("words_result");
        StringBuilder stringBuilder = new StringBuilder();
        Iterator<Object> iterator = wordsResult.iterator();
        while (iterator.hasNext()) {
            org.json.JSONObject jsonObject = (org.json.JSONObject) iterator.next();
            stringBuilder.append(jsonObject.getString("words") + " ");
        }
        return createTextMessage(stringBuilder.toString(), map);
    }*/

    private String createTextMessage(String content, Map<String, String> map) {
        TextMessage textMessage = new TextMessage();
        textMessage.setToUserName(map.get("FromUserName"));
        textMessage.setFromUserName(map.get("ToUserName"));
        textMessage.setMsgType("text");
        textMessage.setContent(content);
        textMessage.setCreateTime(System.currentTimeMillis() / 1000);
        //XStream将Java对象转换成xml字符串
        XStream xStream = new XStream();
        xStream.processAnnotations(TextMessage.class);
        String xml = xStream.toXML(textMessage);
        return xml;
    }


    /**
     * 处理事件推送
     *
     * @param map
     * @return
     */
    private String handleEvent(Map<String, String> map) {
        String event = map.get("Event");
        switch (event) {
            case "CLICK":
                if ("1".equals(map.get("EventKey"))) {
                    TextMessage textMessage = new TextMessage();
                    textMessage.setToUserName(map.get("FromUserName"));
                    textMessage.setFromUserName(map.get("ToUserName"));
                    textMessage.setMsgType("text");
                    textMessage.setContent("你点击了event key是1的按钮");
                    textMessage.setCreateTime(System.currentTimeMillis() / 1000);
                    //XStream将Java对象转换成xml字符串
                    XStream xStream = new XStream();
                    xStream.processAnnotations(TextMessage.class);
                    String xml = xStream.toXML(textMessage);
                    return xml;
                }
                break;
            case "VIEW":
                System.out.println("view");
                break;
            default:
                break;

        }
        return null;
    }

    private String getReplyNewsMessage(Map<String, String> map) {
        NewsMessage newsMessage = new NewsMessage();
        newsMessage.setToUserName(map.get("FromUserName"));
        newsMessage.setFromUserName(map.get("ToUserName"));
        newsMessage.setMsgType("news");
        newsMessage.setCreateTime(System.currentTimeMillis() / 1000);
        newsMessage.setArticleCount(1);
        List<Article> articles = new ArrayList<>();
        Article article = new Article();
        article.setTitle("千锋Java微信公众号开发教程");
        article.setDescription("来自于千锋java，详细的微信公众号开发教程");
        article.setUrl("http://www.qfedu.com");
        article.setPicUrl("http://mmbiz.qpic.cn/mmbiz_jpg/uYWINLib7MFDDuGPgSPRX3B51XTzJLYkkBibOXeib42icyD8F0kTOu1xdp4YYsg5IMMYMWibHvMXxgF7l6rUKsn8mlw/0");
        articles.add(article);
        newsMessage.setArticles(articles);
        //XStream将Java对象转换成xml字符串
        XStream xStream = new XStream();
        xStream.processAnnotations(NewsMessage.class);
        String xml = xStream.toXML(newsMessage);
        return xml;
    }

    /**
     * 获得同义词
     *
     * @param map
     * @return xml格式的字符串
     */
    private String getReplyMessageByWord(Map<String, String> map) {

        TextMessage textMessage = new TextMessage();
        textMessage.setToUserName(map.get("FromUserName"));
        textMessage.setFromUserName(map.get("ToUserName"));
        textMessage.setMsgType("text");
        String content = WordUtil.getWords(map.get("Content"));
        textMessage.setContent(content);

        textMessage.setCreateTime(System.currentTimeMillis() / 1000);

        //XStream将Java对象转换成xml字符串
        XStream xStream = new XStream();
        xStream.processAnnotations(TextMessage.class);
        String xml = xStream.toXML(textMessage);
        return xml;
    }

    /**
     * 获得回复的消息内容
     *
     * @param map
     * @return xml格式的字符串
     */
    private String getReplyMessage(Map<String, String> map) {

        TextMessage textMessage = new TextMessage();
        textMessage.setToUserName(map.get("FromUserName"));
        textMessage.setFromUserName(map.get("ToUserName"));
        textMessage.setMsgType("text");
        textMessage.setContent("欢迎关注本公众号！");
        textMessage.setCreateTime(System.currentTimeMillis() / 1000);

        //XStream将Java对象转换成xml字符串
        XStream xStream = new XStream();
        xStream.processAnnotations(TextMessage.class);
        String xml = xStream.toXML(textMessage);
        return xml;
    }

    @Override
    public Map<String, Object> bindWxUserToCustomer(String name, String phone, String openid) {
        // 直接调用WxCustomerBinder的方法
        return wxCustomerBinder.bindWxUserToCustomer(name, phone, openid);
    }
    
    @Override
    public String getStaffManage(String code) {
        // 根据code获取Access_token的地址
        String url = String.format("https://api.weixin.qq.com/sns/oauth2/access_token?appid=%s&secret=%s&code=%s&grant_type=authorization_code",
                appId,
                secret,
                code);
        // 发送get请求获得access_token
        String result = HttpUtil.doGet(url);
        String accessToken = JSONObject.parseObject(result).getString("access_token");
        String openId = JSONObject.parseObject(result).getString("openid");
        // 拿到access-token后拉取用户的基本信息
        String userInfoUrl = String.format("https://api.weixin.qq.com/sns/userinfo?access_token=%s&openid=%s&lang=zh_CN",
                accessToken,
                openId);
        // 拉取用户信息
        String userInfo = HttpUtil.doGet(userInfoUrl);
        // 解析获得微信号、昵称、头像
        SubscribedUser user = JSONObject.parseObject(userInfo, SubscribedUser.class);
        // 存入微信号昵称对应表（复用现有的用户表）
        TUser tUser = new TUser();
        BeanUtils.copyProperties(user, tUser);
        try {
            userMapper.insertSelective(tUser);
        } catch (Exception e) {
            System.err.println("保存用户信息失败: " + e.getMessage());
        }
        
        // 重定向到技师管理页面，传递openid参数
        return "<script>window.location.href='/wx/staffManage?openid=" + openId + "';</script>";
    }
    
    @Override
    public String getCustomerReservation(String code) {
        // 根据code获取Access_token的地址
        String url = String.format("https://api.weixin.qq.com/sns/oauth2/access_token?appid=%s&secret=%s&code=%s&grant_type=authorization_code",
                appId,
                secret,
                code);
        // 发送get请求获得access_token
        String result = HttpUtil.doGet(url);
        String accessToken = JSONObject.parseObject(result).getString("access_token");
        String openId = JSONObject.parseObject(result).getString("openid");
        // 拿到access-token后拉取用户的基本信息
        String userInfoUrl = String.format("https://api.weixin.qq.com/sns/userinfo?access_token=%s&openid=%s&lang=zh_CN",
                accessToken,
                openId);
        // 拉取用户信息
        String userInfo = HttpUtil.doGet(userInfoUrl);
        // 解析获得微信号、昵称、头像
        SubscribedUser user = JSONObject.parseObject(userInfo, SubscribedUser.class);
        // 存入微信号昵称对应表（复用现有的用户表）
        TUser tUser = new TUser();
        BeanUtils.copyProperties(user, tUser);
        try {
            userMapper.insertSelective(tUser);
        } catch (Exception e) {
            System.err.println("保存用户信息失败: " + e.getMessage());
        }
        
        // 重定向到顾客预约管理页面，传递openid参数
        return "<script>window.location.href='/wx/customerReservation?openid=" + openId + "';</script>";
    }
}
